-- UIDungeonLab
-- Created by chengb Apr/25/2015
-- 死灵实验台界面

UIDungeonLab = class("UIDungeonLab", function()
    return cc.Layer:create();
end);

function UIDungeonLab.create(gridData)
    return UIDungeonLab.new(gridData);
end

-- 材料列表（策划要求不管要不要消耗，全部都要显示出来，那只好写死了）
local LAB_MATERIALS = { 7024, 7023, 7022, };

-- 制作动画播放时间
local PRODUCE_TIME = 1.2;

-- 制作完成后，界面停留的时间
local STAY_TIME = 0.6;

function UIDungeonLab:ctor(gridData)
    -- 初始化
    self:setName("UIDungeonLab");
    local node = cc.CSLoader:createNode("layout/lab/DungeonLab.csb");
    self:addChild(node);
    self.node = node;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    -- 记录格子数据
    self.gridData = gridData;

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIDungeonLab:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 注册事件处理回调函数
function UIDungeonLab:registerEventCallback()
    -- 关注实验台合成物品的事件
    EventMgr.register("UIDungeonLab", event.LAB_COMPOUND_ITEM, function(args)
        local classId = args.classId;

        local function showHint()
            -- 提示合成成功
            local name = ItemM.query(classId, "name");
            alert(string.format(getLocStr("lab_compound_succ"), name));
        end
        performWithDelay(self, showHint, STAY_TIME - 0.05);

        -- 播放奖励特效
        self:playBonusEffect(classId);
    end);

    -- 关注实验台升级装备的事件
    EventMgr.register("UIDungeonLab", event.LAB_UPGRADE_EQUIP, function(args)
        local classId = args.classId;
        local isSucc  = args.isSucc;

        local function showHint()
            local name = ItemM.query(classId, "name");
            local level = EquipM.query(classId, "level");
            if isSucc then
                -- 成功了
                alert(string.format(getLocStr("lab_upgrade_succ"), name, level));

                -- 播放奖励特效
                self:playBonusEffect(classId);
            else
                -- 失败了
                alert(getLocStr("lab_upgrade_failed"));

                -- 移除制作动画
                self:removeProduceEffect();

                -- 重绘
                self:redraw();
            end
        end

        performWithDelay(self, showHint, STAY_TIME - 0.05);
    end);

    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIDungeonLab 界面析构清理");

            -- 移除所有事件关注
            EventMgr.removeAll("UIDungeonLab");

            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():showMenu();
            end

        elseif eventType == "enter" then
            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():hideMenu();
            end
        end
    end);
end

-- 注册点击事件
function UIDungeonLab:registerTouchEvent()
    -- 注册返回按钮点击事件
    local node = self.node;
    local btnBack = findChildByName(node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("button_return");
            UIMgr.getCurrentScene():removeFormByName("UIDungeonLab");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册确定按钮点击事件
    local btnOk = findChildByName(node, "CT/btn_ok");
    local function onOkClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            -- 获取待操作的物品编号
            local classId = self:getLabItemId();

            -- 获取拥有的装备编号（如果尚未合成，返回nil，否则返回对应等级的装备编号）
            local ownId = DungeonLabM.getCurEquipId(classId);
            if not EquipM.isEquipment(classId) or
               not ownId then
                -- 不是装备或者尚未合成该装备
                local ruleId = CompoundM.getCompoundRule(classId);
                local cost = CompoundM.calcCost(ruleId, 1);

                -- 判断材料是否足够
                if not self:checkCost(cost) then
                    alert(getLocStr("lab_compound_lack"));
                    return;
                end

                -- 按钮短暂置灰
                setClickFrequency(sender, PRODUCE_TIME + 0.7);

                -- 播放制作动画
                self:playProduceEffect();

                local function doCompound()
                    -- 合成
                    local pos = self.gridData:getPos();
                    DungeonActionM.go("lab_compound_item", pos);
                end

                performWithDelay(self, doCompound, PRODUCE_TIME);
            else
                -- 已经合成该装备
                if EquipM.findMaxEquip(classId) == ownId then
                    -- 已经满级
                    local name = ItemM.query(classId, "name");
                    alert(string.format(getLocStr("lab_equip_level_upper"), name));
                    return;
                else
                    -- 获取下一级装备
                    local nextId = EquipM.query(ownId, "next_class_id");
                    local ruleId = CompoundM.getCompoundRule(nextId);
                    local cost = CompoundM.calcCost(ruleId, 1);

                    -- 判断材料是否足够
                    if not self:checkCost(cost) then
                        alert(getLocStr("lab_upgrade_lack"));
                        return;
                    end

                    -- 按钮短暂置灰
                    setClickFrequency(sender, PRODUCE_TIME + 0.7);

                    -- 播放制作动画
                    self:playProduceEffect();

                    local function doCompound()
                        -- 升级
                        local pos = self.gridData:getPos();
                        DungeonActionM.go("lab_upgrade_equip", pos);
                    end

                    performWithDelay(self, doCompound, PRODUCE_TIME);
                end
            end
        end
    end
    btnOk:addTouchEventListener(onOkClick);
end

-- 播放奖励特效
function UIDungeonLab:playBonusEffect(classId)
    -- 移除制作特效
    self:removeProduceEffect();

    -- 如果获得了物品，播放飞入包裹的动画
    if classId then
        -- 先显示物品图标
        local buildingImg = findChildByName(self.node, "CT/icon");
        local iconPath = getItemIconPath(ItemM.query(classId, "icon"));
        buildingImg:loadTexture(iconPath);

        -- 播放飞入动画
        local function playAnim()
            local grid = UIDungeonMgr.getCurLevel():getAllGrids()[18];
            pickupEquipEffect(grid, UIDungeonMgr.getCurLevel():getEquipNode(), iconPath, classId, 1);

            -- 获得道具音效
            AudioM.playFx("get_bone");

            -- 关闭界面
            UIMgr.getCurrentScene():removeFormByName("UIDungeonLab");
        end

        -- 短暂停留
        performWithDelay(self, playAnim, STAY_TIME);
    end
end

-- 移除制作动画
function UIDungeonLab:removeProduceEffect()
    local effectNode = findChildByName(self.node, "CT/effect_node");
    effectNode:removeAllChildren();
end

-- 播放制作动画
function UIDungeonLab:playProduceEffect()
    -- 播放制作特效
    local effectNode = findChildByName(self.node, "CT/effect_node");
    playEffect(effectNode, 1151);
end

-- 重绘
function UIDungeonLab:redraw()
    local descLabel  = findChildByName(self.node, "CT/desc");
    local iconImg    = findChildByName(self.node, "CT/icon");
    local titleLabel = findChildByName(self.node, "CT/title_node/title");
    local btnOk      = findChildByName(self.node, "CT/btn_ok");

    -- 查询建筑配置
    local class = self.gridData.class;
    local labId = self.gridData.labId;
    local labInfo = DungeonLabM.query(labId);
    local buildingInfo = BuildingBonusM.queryBuildingView(class);

    -- 标题
    titleLabel:setString(buildingInfo["title"]);

    -- 图片
    iconImg:loadTexture(getLevelItemIconPath(labInfo["icon"]));

    iconImg:setScale(1.0);
    TextStyleM.setTextStyle(btnOk, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    TextStyleM.setArtWordTitleStyle(titleLabel);
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);

    -- 获取待操作的装备编号
    local classId = self:getLabItemId();

    -- 对话内容
    local dialog = DungeonLabM.query(self.gridData.labId, "desc") .. "\n";
    local viewText = "";
    local ownId = DungeonLabM.getCurEquipId(classId);
    if not EquipM.isEquipment(classId) or
       not ownId then
        -- 不是装备，或者尚未合成该装备
        local ruleId = CompoundM.getCompoundRule(classId);
        if not ruleId or ruleId == "" then
            trace("UIDungeonLab", "获取不到物品(%d)的合成规则", classId);
            return;
        end

        -- 策划要求写成：'xx、xx5个'这种格式，只好默认每种材料的个数都相同了
        local cost = CompoundM.calcCost(ruleId, 1);
        local costStr = self:getCostStr(cost);
        local amount = cost[1][3];
        dialog = dialog .. string.format(getLocStr("lab_cost_desc"), costStr, amount);

        -- 按钮文本
        local name = ItemM.query(classId, "name");

        -- 因为俄语显示“制造xxx”会超长，所以只显示“制造”
        if getLang() == "ru" then
            viewText = getLocStr("lab_button_text");
        else
            viewText = string.format(getLocStr("lab_button_text"), name);
        end

        -- 重绘消耗
        self:redrawCost(cost);
    else
        -- 已经合成该装备
        local name = ItemM.query(ownId, "name");
        local level = EquipM.query(ownId, "level");
        viewText = string.format(getLocStr("lab_button_text2"), name, level);
        local cost;
        if EquipM.findMaxEquip(ownId) ~= ownId then
            -- 还没满级
            -- 获取下一级装备
            local nextClassId = EquipM.query(ownId, "next_class_id");
            local ruleId = CompoundM.getCompoundRule(nextClassId);
            if not ruleId or ruleId == "" then
                trace("UIDungeonLab", "获取不到物品(%d)的合成规则", classId);
                return;
            end

            -- 策划要求写成：'xx、xx5个'这种格式，只好默认每种材料的个数都相同了
            cost = CompoundM.calcCost(ruleId, 1);
            local costStr = self:getCostStr(cost);
            local amount = cost[1][3];
            dialog = dialog .. string.format(getLocStr("lab_cost_desc2"), costStr, amount);
        end

        -- 重绘消耗
        self:redrawCost(cost);
    end

    applyString(descLabel, dialog);
    btnOk:setTitleText(viewText);

    -- 按钮可点击
    btnOk:setTouchEnabled(true);
    btnOk:setBright(true);
end

-- 重绘消耗
function UIDungeonLab:redrawCost(cost)
    local costPart = findChildByName(self.node, "CT/cost_part");

    -- 获取需求数量
    local function getNeedAmount(classId)
        if type(cost) ~= 'table' then
            return 0;
        end

        for _, arr in pairs(cost) do
            if arr[2] == classId then
                return arr[3];
            end
        end
        return 0;
    end

    for i, id in pairs(LAB_MATERIALS) do
        local child = findChildByName(costPart, "cost_node" .. i);

        -- 显示材料图标
        local iconImg = findChildByName(child, "icon");
        local iconPath = getItemIconPath(ItemM.query(id, "icon"));
        iconImg:loadTexture(iconPath);
        iconImg:setScale(0.7);
        iconImg:setPositionY(10);

        -- 显示数量信息
        local amountLabel = findChildByName(child, "amount");
        local needAmount = getNeedAmount(id);
        local curAmount = ItemM.getAmount(ME.user, id);

        -- 消耗不足时，显示红色
        if curAmount < needAmount then
            TextStyleM.setTextStyle(amountLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_RED);
        else
            TextStyleM.setTextStyle(amountLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE);
        end

        if needAmount <= 0 then
            -- 无需消耗
            amountLabel:setString(curAmount .. "/-");
        else

            amountLabel:setString(curAmount .. "/" .. needAmount);
        end

    end
end

-- 获取待操作的装备或物品编号
function UIDungeonLab:getLabItemId()
    local labId = self.gridData.labId;
    local labInfo = DungeonLabM.query(labId);
    if not labInfo then
        error("获取实验台配置失败。");
        return nil;
    end

    return labInfo["class_id"];
end

-- 获取消耗描述
function UIDungeonLab:getCostStr(costList)
    local str = "";

    -- 根据id降序
    table.sort(costList, function(arr1, arr2) return arr1[2] > arr2[2]; end);

    for i, arr in pairs(costList) do
        if not EquipM.isEquipment(arr[2]) then
            local name = ItemM.query(arr[2], "name");
            str = str .. name;
            if i < #costList then
                str = str .. getLocStr("pause_mark");
            end
        end
    end

    return str;
end

-- 检查消耗是否足够
function UIDungeonLab:checkCost(costList)
    for _, arr in pairs(costList) do
        if ItemM.getAmount(ME.user, arr[2]) < arr[3] then
            trace("UIDungeonLab", "物品(%d)数量不足。", arr[2]);
            return false;
        end
    end
    return true;
end









